﻿using System;
using System.Collections;


namespace Chess_Model
{

    public class ChessUtilities
    {
        
        // Return true if the coordinate is valid
        public static bool isInRange(int x, int y)
        {
            return (x > -1 && x < ChessBoard.X_RANGE) && 
                   (y > -1 && y < ChessBoard.Y_RANGE);
        }
        public static bool isInRange(Position pos)
        {
            return isInRange(pos.x, pos.y);
        }
        
        // Print out the list of moves
        public static void printMoves(ArrayList moves)
        {
            foreach (Position pos in moves)
            {
                Console.WriteLine(pos);
            }
        }


        //
        // Helper methods to facilate move generation process
        // Loop through x-direction and add x (changing) and y (constant) to
        //      the list of moves except the current position.
        //
        //  Arguments:
        //      'moves' is an arraylist to which these methods will add moves.
        //      'xPos' and 'yPos' are the current coordinates of the piece.
        //
        //  Exception will be thrown if arguments are invalid (such as null pointer
        //      or out-of-range coordinates.
        //
        public static void addHorizontalMoves(ArrayList moves, int xPos, int yPos)
        {
            if (moves == null || !isInRange(xPos, yPos))
                throw new ArgumentException();
            for (int i = 0; i < ChessBoard.X_RANGE; i++)
            {
                if (i != xPos)
                    moves.Add(new Position(i, yPos));
            }
        }


        //
        // Loop through y-direction and add x (constant) and y (changing) to
        //      the list of moves except the current position.
        //
        //  Arguments:
        //      'moves' is an arraylist to which these methods will add moves.
        //      'xPos' and 'yPos' are the current coordinates of the piece.
        //
        //  Exception will be thrown if arguments are invalid (such as null pointer
        //      or out-of-range coordinates.
        //
        public static void addVerticalMoves(ArrayList moves, int xPos, int yPos)
        {
            if (moves == null || !isInRange(xPos, yPos))
                throw new ArgumentException();
            for (int j = 0; j < ChessBoard.Y_RANGE; j++)
            {
                if (j != yPos)
                    moves.Add(new Position(xPos, j));
            }
        }


        //
        // Generate moves in diagonal direction given current position and
        //      appropriate stepping offsets.
        // Note: [0,0] is top-left corner. x is horizontal, y is vertical. 
        //     
        //               NORTH
        //       x-1, y-1  |  x+1, y-1      
        //                 |
        //       WEST------p------EAST
        //                 |   
        //       x-1, y+1  |  x+1, y+1
        //               SOUTH
        //  For example, pair (xStep, yStep) of (1, -1) would keep the piece
        //      moving in NORTH_EAST direction, and so on.
        //
        //  Arguments:
        //      'moves' is an arraylist to which these methods will add moves.
        //      'xPos' and 'yPos' are the current coordinates of the piece.
        //      'xStep' and 'yStep' are the constants to be added to x and y
        //          coordinates (both at the same time) to create a diagonal in
        //          a given direction. See the picture above.
        //
        //  Exception will be thrown if arguments are invalid (such as null pointer
        //      or out-of-range coordinates.
        //
        public static void addDiagonalMoves(ArrayList moves, int xPos, int yPos, int xStep, int yStep)
        {
            if (moves == null || !isInRange(xPos, yPos))
                throw new ArgumentException();

            int i = xPos;
            int j = yPos;

            while (ChessUtilities.isInRange(i, j))
            {
                if (!(i == xPos && j == yPos))
                {
                    //Position p = new Position(i, j);
                    //Console.WriteLine(p);
                    moves.Add(new Position(i, j));
                }
                i += xStep;
                j += yStep;
            }
        }

    }
}
